home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
pmpsrc11.zip
/
PMPTEST.C
< prev
next >
Wrap
Text File
|
1991-03-22
|
10KB
|
429 lines
/*
pmptest.c
A program to test the hardware (modem) setup for PMP
August, 1989
Andrew C. Payne
*/
/* ----- Includes ----- */
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#define EXTERN
#include "types.h"
#include "ports.h"
#include "keys.h"
int monochrome;
#define VIDEO 0x10
#define TRUE 1
#define FALSE 0
#define BITTIME 1988 /* 1200 baud bit time in ticks */
#define CAPSIZE 2400 /* number of capture transitions */
int TXState; /* current transmit (PTT) state */
int TXLev;
int prevRXCarrier; /* prev values to minimize screen updates */
int prevRXLevel;
int capbuf[CAPSIZE];
/* ----- Low Level Screen Control ----- */
/* v_setctype(start,end)
Set the cursor size: start and end.
*/
void cdecl v_setctype(int s,int e)
{
_AH = 1;
_CH = s;
_CL = e;
geninterrupt(VIDEO);
}
/* curoff()
Turns the cursor off.
*/
void cdecl curoff(void)
{
v_setctype(0x0f,0x0f);
}
/* curon()
Turns the cursor on.
*/
void cdecl curon(void)
{
if(monochrome)
v_setctype(12,13);
else
v_setctype(6,7);
}
/* putstring(x,y,len,attr,string)
Given an absolute screen position, a buffered length, and a string,
write string to screen. (FAST!!)
*/
void putstring(int x, int y, int len, char attr, char *s)
{
char buf[80*2]; /* buffer for string */
char *p;
int i;
/* fill buffer with screen data */
p = buf;
for(i=0; i<len; i++) {
if(*s)
*p++ = *s++;
else
*p++ = ' '; /* buffer with spaces */
*p++ = attr; /* character attribute */
}
/* write string to screen */
puttext(x,y,x+len-1,y,buf);
}
void TitleScreen()
{
clrscr();
cprintf("┌─────────────────────────────────────────────────────────────────────────────┐\r\n");
cprintf("│ PMP Test Version 0.7 Alignment and Test Program for Poor Man's Packet │\r\n");
cprintf("│ Copyright (c) 1990 Andrew C. Payne All rights reserved. │\r\n");
cprintf("└─────────────────────────────────────────────────────────────────────────────┘\r\n");
cprintf(" Commands:\r\n");
cprintf(" [ESC] to exit\r\n");
cprintf(" [SPACE] to toggle transmit on and off\r\n");
cprintf(" [F1] for on-air modem alignment mode\r\n");
cprintf(" [F2] to toggle transmit data level\r\n");
cprintf(" [F3] to select 600hz transmit modulation\r\n");
cprintf(" [F4] for loopback alignment (not implemented)\r\n");
gotoxy(1,22);
cprintf(" Carrier Receive Transmit Push To\r\n");
cprintf(" Detect Data Data Talk\r\n");
}
void InitParameters()
{
/* default I/O ports */
PTTPort = TXPort = 0x378;
TXBit = 1;
PTTBit = 2;
CDPort = RXPort = 0x379;
RXBit = 8;
CDBit = 0x80;
CDLevel = 0;
}
/* ----- Low Level I/O ----- */
/* RXCarrier()
Returns TRUE if receive carrier detected.
*/
int RXCarrier()
{
register byte x;
x = inportb(CDPort) & CDBit;
return CDLevel ? x : !x;
}
/* RXLevel()
Returns the current level of the RX data line.
*/
int RXLevel()
{
return (inportb(RXPort) & RXBit) == RXBit;
}
/* TXKey(state)
Sets the transmitter state to the state given (TRUE = 1 = keyup).
Updates screen status.
*/
void TXKey(int state)
{
if(state) {
outportb(PTTPort,inportb(PTTPort) | PTTBit);
putstring(59,24,4,0x70," TX ");
} else {
outportb(PTTPort,inportb(PTTPort) & ~PTTBit);
putstring(59,24,4,0," ");
}
}
/* TXLevel(x)
Sets the TX data level to the level specified.
Updates screen status.
*/
void TXLevel(int x)
{
if(x) {
putstring(42,24,4,0x70," TD ");
outportb(TXPort,inportb(TXPort) | TXBit);
} else {
outportb(TXPort,inportb(TXPort) & ~TXBit);
putstring(42,24,4,0," ");
}
TXLev = x;
}
/* UpdateScreen()
Update the screen status to reflect the current Carrier Detect
level and the current receive level.
*/
void UpdateScreen()
{
int t;
/* show status of CD */
if((t = RXCarrier()) != prevRXCarrier) {
prevRXCarrier = t;
if(prevRXCarrier)
putstring(7,24,4,0x70," CD ");
else
putstring(7,24,4,0," ");
}
/* show receive level */
if((t = RXLevel()) != prevRXLevel) {
prevRXLevel = t;
if(prevRXLevel)
putstring(23,24,4,0x70," RD ");
else
putstring(23,24,4,0," ");
}
}
/* SquareWave()
Generate a 600hz square wave on the output until a key is pressed.
*/
void SquareWave(void)
{
word from;
/* show what is going on on the screen */
gotoxy(1,13);
cprintf("┌────────────────────────────── 600hz Transmit ───────────────────────────────┐\r\n");
cprintf("│ │\r\n");
cprintf("│ Transmitting 600hz square wave │\r\n");
cprintf("│ │\r\n");
cprintf("│ │\r\n");
cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
from = timer();
while(!keypressed()) /* wait tell key interrupt */
transit(from -= BITTIME);
putstring(1,13,79,0,""); /* clear the lines */
putstring(1,14,79,0,"");
putstring(1,15,79,0,"");
putstring(1,16,79,0,"");
putstring(1,17,79,0,"");
putstring(1,18,79,0,"");
getkey(); /* gobble */
}
/* Alignment()
Waits for carrier detect (or user keystroke), and captures a
few transitions of data. Computes and displays alignment information
from transition timing.
*/
void Alignment(void)
{
int i;
word t,t1,t2;
int actual,delta;
long deltahi,deltalo;
int deltahict, deltaloct;
char s[100];
/* show what is going on on the screen */
gotoxy(1,13);
cprintf("┌────────────────────────────── Modem Alignment ──────────────────────────────┐\r\n");
cprintf("│ Adjust modem for lowest numbers possible (see manual for more info) │\r\n");
cprintf("│ │\r\n");
cprintf("│ │\r\n");
cprintf("│ │\r\n");
cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
loop:
while(!RXCarrier() && !keypressed())
;
if(keypressed()) {
putstring(1,13,79,0,""); /* clear the lines */
putstring(1,14,79,0,"");
putstring(1,15,79,0,"");
putstring(1,16,79,0,"");
putstring(1,17,79,0,"");
putstring(1,18,79,0,"");
getkey(); /* gobble key */
return;
}
UpdateScreen();
/* start capture */
deltahi = deltalo = deltahict = deltaloct = 0;
disable();
for(i=0; i<CAPSIZE; i++) {
t2 = waittrans(t1-20000);
t = t1 - t2;
t1 = t2;
actual = ((t + 994) / BITTIME) * BITTIME;
delta = actual - t;
if(RXLevel()) {
deltahi += delta;
deltahict++;
} else {
deltalo += delta;
deltaloct++;
}
if(!RXCarrier())
break;
}
enable();
UpdateScreen();
sprintf(s,"Low -> High error: %5ld%% High -> Low error: %5ld%%",
(deltahi / deltahict) * (long)100 / BITTIME,
(deltalo / deltaloct) * (long)100 / BITTIME);
putstring(15,16,60,7,s);
delay(1000);
goto loop;
}
/* Loopback()
Does a loopback alignemnt. Assumes that the transmit audio is
looped back into the receive audio.
*/
void Loopback()
{
word t,t1,d;
int i,j,k;
long deltalo, deltahi;
char s[100];
/* show what's going on */
gotoxy(1,13);
cprintf("┌──────────────────────────── Loopback Alignment ─────────────────────────────┐\r\n");
cprintf("│ Adjust modem for lowest numbers possible (see manual for more info) │\r\n");
cprintf("│ │\r\n");
cprintf("│ │\r\n");
cprintf("│ │\r\n");
cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
/* loop until keypressed */
while(!keypressed()) {
deltalo = deltahi = 0;
TXLevel(0);
delay(100);
disable();
deltahi = 0;
t = timer();
j = RXLevel();
transit(t -= BITTIME);
waituntil(t -= 50000);
waituntil(t -= 50000);
i = RXLevel();
enable();
delay(100);
cprintf("%d %d\r\n",j,i);
}
getkey();
#ifdef ANDY
/* do a second-long sample */
for(i=0; i<600; i++) {
/* do a low->high transition */
transit(t -= BITTIME); /* do a transition */
deltahi = t - waittrans(t - 50000);
break;
d = RXLevel();
if(d)
deltahi++;
/* do a high-low transition */
transit(t -= BITTIME); /* do a transition */
d = RXLevel();
if(!d)
deltalo++;
}
enable();
sprintf(s,"%5ld %5ld",
deltahi, deltalo);
putstring(15,16,60,7,s);
}
getkey(); /* gobble the key */
#endif
}
/* HandleKey()
Handles user's keystrokes.
*/
int HandleKey()
{
KEY k;
switch(getkey()) {
case ESC:
case ALTX:
return TRUE; /* done! */
case SPC:
TXState = !TXState;
TXKey(TXState);
break;
case F1: /* on-air alignment */
Alignment();
break;
case F2: /* toggle TX level */
TXLev = !TXLev;
TXLevel(TXLev);
break;
case F3: /* 600hz square wave */
SquareWave();
break;
case F4: /* loopback test */
/* Loopback();
*/
break;
}
return FALSE;
}
/* ----- Main Program ----- */
main(int argc, char **argv)
{
/* Initialize */
monochrome = TRUE;
TXKey(TXState = FALSE);
TitleScreen();
curoff();
InitParameters();
/* loop, handling keystrokes and showing current status */
while(TRUE) {
if(keypressed()) {
if(HandleKey())
break;
}
UpdateScreen();
}
/* clean up and exit */
clrscr();
curon();
TXKey(FALSE); /* drop transmit */
_exit(0);
}